iT邦幫忙

2024 iThome 鐵人賽

DAY 19
0
Modern Web

Vue UI 探索:PrimeVue 學習之旅系列 第 19

[Day19] 結合 vee-validate 表單驗證

  • 分享至 

  • xImage
  •  

在 PrimeVue 中,各類型輸入框提供 invalid 樣式提示使用者輸入內容不符合驗證規則,本篇結合 vee-validate 表單驗證工具,說明安裝、設定及使用流程:

  1. 安裝 vee-validate,並安裝驗證規則及多國語系相關套件。

npm install vee-validate @vee-validate/rules @vee-validate/i18n

當前版本:

"@vee-validate/i18n": "^4.13.2"

"@vee-validate/rules": "^4.13.2"

"vee-validate": "^4.13.2"

  1. 在 main.js 設定:
// main.js
...
import { Field, Form, ErrorMessage, defineRule, configure } from 'vee-validate';
// 引入 VeeValidate 的 i18n 功能
import { localize, setLocale } from '@vee-validate/i18n';
// 引入 VeeValidate 的繁體中文語系檔
import zhTW from '@vee-validate/i18n/dist/locale/zh_TW.json';
// 引入 VeeValidate 的驗證規則
import { all } from '@vee-validate/rules';

// 使用 Object.keys 將 AllRules 轉為陣列,使用 forEach 迴圈將驗證規則加入 VeeValidate
Object.entries(all).forEach(([name, rule]) => {
  defineRule(name, rule);
});

// 將當前 VeeValidate 的語系設定為繁體中文
configure({
  generateMessage: localize({ zh_TW: zhTW }),
  validateOnInput: true
});
setLocale('zh_TW');
...

// 掛載 VeeValidate 元件
app.component('VField', Field);
app.component('VForm', Form);
app.component('ErrorMessage', ErrorMessage);

app.mount('#app')
  1. 在頁面上的使用
    • 引入 useForm,可解構 handleSubmit、defineField、errors 分別取得發送方法、定義欄位及各欄位錯誤訊息等資訊。
    • 在 useForm 內設定初始值(initialValues)及欄位驗證規則(validationSchema)。
    • 定義欄位,並在 html tag 上綁定 v-model 及 v-bind 的屬性。
    • 在 submit 事件發送時使用 handleSubmit 方法,並解構出 resetForm 方法可整張表單回到預設值。
    • 若有 errors 訊息,顯示於畫面中提示使用者。
<script setup>
import { useForm } from 'vee-validate';

const { handleSubmit, defineField, errors } = useForm({
    initialValues: { // 預設值
        email: '',
        pwd: ''
    },
    validationSchema: { // 驗證規則
        email: {
            required: true,
            email: true
        },
        pwd: {
            required: true,
            min: 8
        }
    }
});

const [email, emailProps] = defineField('email'); // 定義欄位
const [pwd, pwdProps] = defineField('pwd');

const onSubmit = handleSubmit(async (values, { resetForm }) => { // 表單發送
    console.log(values);
    resetForm();
});
</script>

<template>
    <main class="p-6">
        <form>
            <div class="grid grid-cols-4 gap-4">
                <form>
                    <label for="email" class="block text-surface-900 dark:text-surface-0 text-lg font-medium mb-1">帳號</label>
                    <InputText
                        id="email"
                        v-bind="emailProps"
                        v-model.trim="email"
                        type="text"
                        placeholder="請輸入帳號"
                        class="py-2 mb-1"
                        :invalid="!!errors?.['email']"
                        :class="{ 'p-invalid': !!errors['email'] }"
                        fluid
                    />
                    <span class="block text-red-500 mb-4">{{ errors?.['email'] }}</span>

                    <label for="pwd" class="block text-surface-900 dark:text-surface-0 font-medium text-lg mb-1">密碼</label>
                    <Password
                        inputId="pwd"
                        v-bind="pwdProps"
                        v-model="pwd"
                        placeholder="請輸入密碼"
                        :toggleMask="true"
                        :feedback="false"
                        class="py-2 mb-1"
                        :inputProps="{ autocomplete: true }"
                        :invalid="!!errors?.['pwd']"
                        :class="{ 'p-invalid': !!errors['pwd'] }"
                        fluid
                    />
                    <span class="block text-red-500 mb-6">{{ errors?.['pwd'] }}</span>

                    <Button label="登入" class="py-2" @click.prevent="onSubmit" fluid />
                </form>
            </div>
        </form>
    </main>
</template>

vee-validate

參考連結:https://vee-validate.logaretm.com/v4/api/use-form#composable-api


上一篇
[Day18] Form - SelectButton
下一篇
[Day20] Panel - Accordion
系列文
Vue UI 探索:PrimeVue 學習之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言